package com.shop.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.shop.constant.ScheduleConstants;
import com.shop.mapper.QrtzJobDetailsMapper;
import com.shop.model.PageParam;
import com.shop.model.dto.Job;
import com.shop.model.vo.Rsp;
import com.shop.util.CronUtils;
import com.shop.util.ScheduleUtils;
import lombok.AllArgsConstructor;
import org.quartz.*;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * (QrtzJobDetails)表服务接口
 *
 * @author makejava
 * @since 2020-11-28 09:26:17
 */
@Service
@AllArgsConstructor
public class QrtzJobDetailsService {
    private final QrtzJobDetailsMapper qrtzJobDetailsMapper;
    private final Scheduler scheduler;

    public PageInfo<Job> getJobList(PageParam<Job> pageParam) {
        PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize());
        List<Job> list = qrtzJobDetailsMapper.selectList(null);
        list.forEach(e -> {
            e.setNextValidTime(CronUtils.getNextExecution(e.getCronExpression()));
        });
        return new PageInfo<>(list);
    }

    public Rsp insert(Job job) throws ClassNotFoundException, SchedulerException {
        boolean expression = CronExpression.isValidExpression(job.getCronExpression());
        if (!expression) {
            return Rsp.fail().msg("cron表达式错误!");
        }
        //判断类存不存在
        try {
            Class.forName(job.getJobClassName());
        } catch (ClassNotFoundException e) {
            return Rsp.fail().msg("找不到该类!");
        }
        ScheduleUtils.createScheduleJob(scheduler, job);
        qrtzJobDetailsMapper.insert(job);
        return Rsp.success(null);
    }

    public Rsp update(Job job) {
        try {
            updateSchedulerJob(job);
        } catch (SchedulerException e) {
            e.printStackTrace();
            return Rsp.fail().msg("更新失败");
        } catch (ClassNotFoundException e) {
            return Rsp.fail().msg("类找不到");
        }
        qrtzJobDetailsMapper.updateById(job);
        return Rsp.success(null);
    }

    public Rsp delete(Job job) {
        try {
            scheduler.deleteJob(ScheduleUtils.getJobKey(job.getJobName(), job.getJobGroup()));
        } catch (SchedulerException e) {
            e.printStackTrace();
            return Rsp.fail().msg("删除失败");
        }
        qrtzJobDetailsMapper.deleteById(job.getId());
        return Rsp.success(null);
    }

    public Rsp pauseAndStart(Job job) {
        try {
            String status = job.getStatus();
            if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) {
                resumeJob(job);
            } else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) {
                pauseJob(job);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
            return Rsp.fail().msg("状态修改失败失败");
        }
        return Rsp.success(null);
    }

    /**
     * 立即执行
     *
     * @param job
     * @return
     */
    public Rsp run(Job job) {
        try {
            scheduler.triggerJob(ScheduleUtils.getJobKey(job.getJobName(), job.getJobGroup()), new JobDataMap());
        } catch (SchedulerException e) {
            e.printStackTrace();
            return Rsp.fail().msg("启动失败");
        }
        return Rsp.success(null);
    }

    public void pauseJob(Job job) throws SchedulerException {
        job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
        int rows = qrtzJobDetailsMapper.updateById(job);
        if (rows > 0) {
            scheduler.pauseJob(ScheduleUtils.getJobKey(job.getJobName(), job.getJobGroup()));
        }
    }

    /**
     * 恢复任务
     *
     * @param job 调度信息
     */
    public void resumeJob(Job job) throws SchedulerException {
        job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
        int rows = qrtzJobDetailsMapper.updateById(job);
        if (rows > 0) {
            scheduler.resumeJob(ScheduleUtils.getJobKey(job.getJobName(), job.getJobGroup()));
        }
    }

    /**
     * 更新任务
     *
     * @param job 任务对象
     */
    public void updateSchedulerJob(Job job) throws SchedulerException, ClassNotFoundException {
        // 判断是否存在
        JobKey jobKey = ScheduleUtils.getJobKey(job.getJobName(), job.getJobGroup());
        if (scheduler.checkExists(jobKey)) {
            // 防止创建时存在数据问题 先移除，然后在执行创建操作
            scheduler.deleteJob(jobKey);
        }
        ScheduleUtils.createScheduleJob(scheduler, job);
    }
}
